package com.xyzq.simpson.apm.web.service.influx;

import com.google.common.base.Splitter;
import com.xyzq.simpson.base.model.Page;
import com.xyzq.simpson.base.text.Text;
import org.apache.commons.lang3.StringUtils;
import org.influxdb.dto.QueryResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.*;

/**
 * @Description:
 * @date 2020/3/26 17:28
 */
public class ResultWrapper {

    private static Logger logger = LoggerFactory.getLogger(ResultWrapper.class);

    public static Page<Map> wrapper(QueryResult results) {
        Page<Map> ret = new Page<>();
        List<Map> list = new LinkedList<>();
        if (null == results || null == results.getResults() || 0 == results.getResults().size()) {
            return ret;
        }
        for (QueryResult.Result result : results.getResults()) {
            if(result.hasError()) {
                logger.error("query wrapper error:" + result.getError());
                continue;
            }
            List<QueryResult.Series> series = result.getSeries();
            if(null == series || 0 == series.size()) {
                return ret;
            }
            for (QueryResult.Series serie : series) {
                List<List<Object>> values = serie.getValues();
                List<String> colums = serie.getColumns();
                for (List<Object> value : values) {
                    Map r = new LinkedHashMap();
                    for(int i=0; i<colums.size(); i++) {
                        r.put(colums.get(i), value.get(i));
                    }
                    list.add(r);
                }
            }
        }
        ret.list = list;
        ret.total = list.size();
        return ret;
    }

    public static Map wrapperOne(QueryResult results) {
        Map ret = new LinkedHashMap();
        if (null == results || null == results.getResults() || 0 == results.getResults().size()) {
            return ret;
        }
        for (QueryResult.Result result : results.getResults()) {
            if(result.hasError()) {
                logger.error("query wrapper error:" + result.getError());
                continue;
            }
            List<QueryResult.Series> series = result.getSeries();
            if(null == series || 0 == series.size()) {
                return ret;
            }
            for (QueryResult.Series serie : series) {
                List<List<Object>> values = serie.getValues();
                List<String> colums = serie.getColumns();
                for (List<Object> value : values) {
                    for(int i=0; i<colums.size(); i++) {
                        ret.put(colums.get(i), value.get(i));
                    }
                }
            }
        }
        return ret;
    }

    public static List<Map<String, Object>> wrapperSeries(QueryResult results) {
        List<Map<String, Object>> ret = new LinkedList<>();
        for (QueryResult.Result result : results.getResults()) {
            if(result.hasError()) {
                logger.error("query wrapper error:" + result.getError());
                continue;
            }
            List<QueryResult.Series> series = result.getSeries();
            if(series == null || series.size() == 0) {
                return ret;
            }
            for (QueryResult.Series serie : series) {
                List<List<Object>> values = serie.getValues();
                List<String> colums = serie.getColumns();
                Map<String, String> tags = serie.getTags();
                Map<String, Object> map = new HashMap<>(tags);
                for (List<Object> value : values) {
                    for(int i=0; i<colums.size(); i++) {
                        map.put(colums.get(i), value.get(i));
                    }
                }
                ret.add(map);
            }
        }
        return ret;
    }

    public static Map<String, Map<String, Object>> wrapperSeriesBuildTagMapKey(QueryResult results) {
        Map<String, Map<String, Object>> ret = new HashMap<>();
        for (QueryResult.Result result : results.getResults()) {
            if(result.hasError()) {
                logger.error("query wrapper error:" + result.getError());
                continue;
            }
            List<QueryResult.Series> series = result.getSeries();
            if(series == null || series.size() == 0) {
                return ret;
            }
            for (QueryResult.Series serie : series) {
                List<List<Object>> values = serie.getValues();
                List<String> colums = serie.getColumns();
                Map<String, String> tags = serie.getTags();
                Map<String, Object> map = new HashMap<>(tags);
                for (List<Object> value : values) {
                    for(int i=0; i<colums.size(); i++) {
                        map.put(colums.get(i), value.get(i));
                    }
                }
                ret.put(tags.values().toString(), map);
            }
        }
        return ret;
    }

    public static List<Map<String, Object>> wrapperSeriesWithSort(QueryResult results, String sortField) {
        List<Map<String, Object>> ret = new LinkedList<>();
        for (QueryResult.Result result : results.getResults()) {
            if(result.hasError()) {
                logger.error("query wrapper error:" + result.getError());
                continue;
            }
            List<QueryResult.Series> series = result.getSeries();
            if(series == null || series.size() == 0) {
                return ret;
            }
            for (QueryResult.Series serie : series) {
                List<List<Object>> values = serie.getValues();
                List<String> colums = serie.getColumns();
                Map<String, String> tags = serie.getTags();
                Map<String, Object> map = new HashMap<>(tags);
                for (List<Object> value : values) {
                    for (int i = 0; i < colums.size(); i++) {
                        map.put(colums.get(i), value.get(i));
                    }
                }
                ret.add(map);
            }
        }
        if(!Text.isBlank(sortField) && ret != null && ret.size() > 1) {
            ret.sort((Map<String, Object> r1, Map<String, Object> r2) ->
                    Double.compare((double) r2.get(sortField), (double) r1.get(sortField)));
        }
        return ret;
    }

    public static List<Map<String, Object>> wrapperOneSerie(QueryResult results) {
        List<Map<String, Object>> ret = new LinkedList<>();
        for (QueryResult.Result result : results.getResults()) {
            if(result.hasError()) {
                logger.error("query wrapper error:" + result.getError());
                continue;
            }
            List<QueryResult.Series> series = result.getSeries();
            if(series == null || series.size() == 0) {
                return ret;
            }
            for (QueryResult.Series serie : series) {
                List<List<Object>> values = serie.getValues();
                List<String> colums = serie.getColumns();
                for (List<Object> value : values) {
                    Map<String, Object> map = new HashMap<>();
                    for(int i=0; i<colums.size(); i++) {
                        map.put(colums.get(i), value.get(i));
                    }
                    ret.add(map);
                }
            }
        }
        return ret;
    }

    public static Set getField(QueryResult results, String field) {
        Set set = new HashSet();
        if (null == results || null == results.getResults() || 0 == results.getResults().size()) {
            return set;
        }
        for (QueryResult.Result result : results.getResults()) {
            if(result.hasError()) {
                logger.error("query wrapper error:" + result.getError());
                continue;
            }
            List<QueryResult.Series> series = result.getSeries();
            if(null == series || 0 == series.size()) {
                return set;
            }
            for (QueryResult.Series serie : series) {
                List<List<Object>> values = serie.getValues();
                List<String> colums = serie.getColumns();
                for (List<Object> value : values) {
                    for(int i=0; i<colums.size(); i++) {
                        if(field.equalsIgnoreCase(colums.get(i))) {
                            set.add(value.get(i));
                        }
                    }
                }
            }
        }
        return set;
    }

    public static List getField2List(QueryResult results, String field) {
        List list = new ArrayList();
        if (null == results || null == results.getResults() || 0 == results.getResults().size()) {
            return list;
        }
        for (QueryResult.Result result : results.getResults()) {
            if(result.hasError()) {
                logger.error("query wrapper error:" + result.getError());
                continue;
            }
            List<QueryResult.Series> series = result.getSeries();
            if(null == series || 0 == series.size()) {
                return list;
            }
            for (QueryResult.Series serie : series) {
                List<List<Object>> values = serie.getValues();
                List<String> colums = serie.getColumns();
                for (List<Object> value : values) {
                    for(int i=0; i<colums.size(); i++) {
                        if(field.equalsIgnoreCase(colums.get(i))) {
                            list.add(value.get(i));
                        }
                    }
                }
            }
        }
        return list;
    }

    public static Set getSerialNos(QueryResult results, String field) {
        Set set = new LinkedHashSet();
        if (null == results || null == results.getResults() || 0 == results.getResults().size()) {
            return set;
        }
        for (QueryResult.Result result : results.getResults()) {
            if(result.hasError()) {
                logger.error("query wrapper error:" + result.getError());
                continue;
            }
            List<QueryResult.Series> series = result.getSeries();
            if(null == series || 0 == series.size()) {
                return set;
            }
            for (QueryResult.Series serie : series) {
                List<List<Object>> values = serie.getValues();
                List<String> colums = serie.getColumns();
                for (List<Object> value : values) {
                    for(int i=0; i<colums.size(); i++) {
                        if(field.equalsIgnoreCase(colums.get(i))) {
                            String sns = String.valueOf(value.get(i));
                            sns = StringUtils.strip(sns, "[]");
                            List<String> tmp = Splitter.on(",").omitEmptyStrings().trimResults().splitToList(sns);
                            for(int j=0; j<tmp.size(); j++) {
                                set.add(tmp.get(tmp.size()-1-j));
                            }
                        }
                    }
                }
            }
        }
        return set;
    }

    public static Set getTagFieldWithSeries(QueryResult results) {
        Set set = new HashSet();
        if (null == results || null == results.getResults() || 0 == results.getResults().size()) {
            return set;
        }
        for (QueryResult.Result result : results.getResults()) {
            if(result.hasError()) {
                logger.error("query wrapper error:" + result.getError());
                continue;
            }
            List<QueryResult.Series> series = result.getSeries();
            if(null == series || 0 == series.size()) {
                return set;
            }
            for (QueryResult.Series serie : series) {
                Map<String, String> tags = serie.getTags();
                set.addAll(tags.values());
            }
        }
        return set;
    }
}
